<!DOCTYPE html>
<html>

<head>
  <title>Using Transactions in Quarkus</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/transaction" />
  <meta property="og:title" content="Using Transactions in Quarkus" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/transaction">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Using Transactions in Quarkus</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#setting-it-up">Setting it up</a></li>
<li><a href="#starting-and-stopping-transactions-defining-your-boundaries">Starting and stopping transactions: defining your boundaries</a>
<ul class="sectlevel2">
<li><a href="#declarative-approach">Declarative approach</a></li>
<li><a href="#transaction-configuration">Transaction Configuration</a></li>
<li><a href="#reactive-extensions">Reactive extensions</a></li>
<li><a href="#api-approach">API approach</a></li>
</ul>
</li>
<li><a href="#configuring-the-transaction-timeout">Configuring the transaction timeout</a></li>
<li><a href="#configuring-transaction-node-name-identifier">Configuring transaction node name identifier</a></li>
<li><a href="#why-always-having-a-transaction-manager">Why always having a transaction manager?</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus comes with a Transaction Manager and uses it to coordinate and expose transactions to your applications.
Each extension dealing with persistence will integrate with it for you.
And you will explicitly interact with transactions via CDI.
This guide will walk you through all that.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setting-it-up"><a class="anchor" href="#setting-it-up"></a>Setting it up</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You don&#8217;t need to worry about setting it up most of the time as extensions needing it will simply add it as a dependency.
Hibernate ORM for example will include the transaction manager and set it up properly.</p>
</div>
<div class="paragraph">
<p>You might need to add it as a dependency explicitly if you are using transactions directly without Hibernate ORM for example.
Add the following to your <code>pom.xml</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-narayana-jta&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="starting-and-stopping-transactions-defining-your-boundaries"><a class="anchor" href="#starting-and-stopping-transactions-defining-your-boundaries"></a>Starting and stopping transactions: defining your boundaries</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can define your transaction boundaries the easy way, or the less easy way :)</p>
</div>
<div class="sect2">
<h3 id="declarative-approach"><a class="anchor" href="#declarative-approach"></a>Declarative approach</h3>
<div class="paragraph">
<p>The easiest way to define your transaction boundaries is to use the <code>@Transactional</code> annotation on your entry method (<code>javax.transaction.Transactional</code>).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class SantaClausService {

    @Inject ChildDAO childDAO;
    @Inject SantaClausDAO santaDAO;

    @Transactional <i class="conum" data-value="1"></i><b>(1)</b>
    public void getAGiftFromSanta(Child child, String giftDescription) {
        // some transaction work
        Gift gift = childDAO.addToGiftList(child, giftDescription);
        if (gift == null) {
            throw new OMGGiftNotRecognizedException(); <i class="conum" data-value="2"></i><b>(2)</b>
        }
        else {
            santaDAO.addToSantaTodoList(gift);
        }
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This annotation defines your transaction boundaries and will wrap this call within a transaction.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>A <code>RuntimeException</code> crossing the transaction boundaries will rollback the transaction.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><code>@Transactional</code> can be used to control transaction boundaries on any CDI bean at the method level or at the class level to ensure every method is transactional.
That includes REST endpoints.</p>
</div>
<div class="paragraph">
<p>You can control whether and how the transaction is started with parameters on <code>@Transactional</code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>@Transactional(REQUIRED)</code> (default): starts a transaction if none was started, stays with the existing one otherwise.</p>
</li>
<li>
<p><code>@Transactional(REQUIRES_NEW)</code>: starts a transaction if none was started ; if an existing one was started, suspends it and starts a new one for the boundary of that method.</p>
</li>
<li>
<p><code>@Transactional(MANDATORY)</code>: fails if no transaction was started ; works within the existing transaction otherwise.</p>
</li>
<li>
<p><code>@Transactional(SUPPORTS)</code>: if a transaction was started, joins it ; otherwise works with no transaction.</p>
</li>
<li>
<p><code>@Transactional(NOT_SUPPORTED)</code>: if a transaction was started, suspends it and works with no transaction for the boundary of the method ; otherwise works with no transaction.</p>
</li>
<li>
<p><code>@Transactional(NEVER)</code>: if a transaction was started, raises an exception ; otherwise works with no transaction.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p><code>REQUIRED</code> or <code>NOT_SUPPORTED</code> are probably the most useful ones.
This is how you decide whether a method is to be running within or outside a transaction.
Make sure to check the JavaDoc for the precise semantic.</p>
</div>
<div class="paragraph">
<p>The transaction context is propagated to all calls nested in the <code>@Transactional</code> method as you would expect (in this example <code>childDAO.addToGiftList()</code> and <code>santaDAO.addToSantaTodoList()</code>).
The transaction will commit unless a runtime exception crosses the method boundary.
You can override whether an exception forces the rollback or not by using <code>@Transactional(dontRollbackOn=SomeException.class)</code> (or <code>rollbackOn</code>).</p>
</div>
<div class="paragraph">
<p>You can also programmatically ask for a transaction to be marked for rollback.
Inject a <code>TransactionManager</code> for this.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class SantaClausService {

    @Inject TransactionManager tm; <i class="conum" data-value="1"></i><b>(1)</b>
    @Inject ChildDAO childDAO;
    @Inject SantaClausDAO santaDAO;

    @Transactional
    public void getAGiftFromSanta(Child child, String giftDescription) {
        // some transaction work
        Gift gift = childDAO.addToGiftList(child, giftDescription);
        if (gift == null) {
            tm.setRollbackOnly(); <i class="conum" data-value="2"></i><b>(2)</b>
        }
        else {
            santaDAO.addToSantaTodoList(gift);
        }
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Inject the <code>TransactionManager</code> to be able to activate <code>setRollbackOnly</code> semantic.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Programmatically decide to set the transaction for rollback.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="transaction-configuration"><a class="anchor" href="#transaction-configuration"></a>Transaction Configuration</h3>
<div class="paragraph">
<p>Advanced configuration of the transaction is possible with the use of the <code>@TransactionConfiguration</code> annotation that is set in addition to the standard <code>@Transactional</code> annotation on your entry method or at the class level.</p>
</div>
<div class="paragraph">
<p>The <code>@TransactionConfiguration</code> annotation allows to set a timeout property, in seconds, that applies to transactions created within the annotated method.</p>
</div>
<div class="paragraph">
<p>This annotation may only be placed on the top level method delineating the transaction.
Annotated nested methods once a transaction has started will throw an exception.</p>
</div>
<div class="paragraph">
<p>If defined on a class, it is equivalent to defining it on all the methods of the class marked with <code>@Transactional</code>.
The configuration defined on a method takes precedence over the configuration defined on a class.</p>
</div>
</div>
<div class="sect2">
<h3 id="reactive-extensions"><a class="anchor" href="#reactive-extensions"></a>Reactive extensions</h3>
<div class="paragraph">
<p>If your <code>@Transactional</code>-annotated method returns a reactive value, such as:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>CompletionStage</code> (from the JDK)</p>
</li>
<li>
<p><code>Publisher</code> (from  Reactive-Streams)</p>
</li>
<li>
<p>Any type which can be converted to one of the two previous types using Reactive Type Converters</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>then the behaviour is a bit different, because the transaction will not be terminated until the
returned reactive value is terminated. In effect, the returned reactive value will be listened to
and if it terminates exceptionally the transaction will be marked for rollback, and will be committed
or rolled-back only at termination of the reactive value.</p>
</div>
<div class="paragraph">
<p>This allows your reactive methods to keep on working on the transaction asynchronously until their
work is really done, and not just until the reactive method returns.</p>
</div>
<div class="paragraph">
<p>If you need to propagate your transaction context across your reactive pipeline, please see the
<a href="context-propagation">Context Propagation guide</a>.</p>
</div>
</div>
<div class="sect2">
<h3 id="api-approach"><a class="anchor" href="#api-approach"></a>API approach</h3>
<div class="paragraph">
<p>The less easy way is to inject a <code>UserTransaction</code> and use the various transaction demarcation methods.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class SantaClausService {

    @Inject ChildDAO childDAO;
    @Inject SantaClausDAO santaDAO;
    @Inject UserTransaction transaction;

    public void getAGiftFromSanta(Child child, String giftDescription) {
        // some transaction work
        try {
            transaction.begin();
            Gift gift = childDAO.addToGiftList(child, giftDescription);
            santaDAO.addToSantaTodoList(gift);
            transaction.commit();
        }
        catch(SomeException e) {
            // do something on Tx failure
            transaction.rollback();
        }
    }
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>You cannot use <code>UserTransaction</code> in a method having a transaction started by a <code>@Transactional</code> call.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-the-transaction-timeout"><a class="anchor" href="#configuring-the-transaction-timeout"></a>Configuring the transaction timeout</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can configure the default transaction timeout, the timeout that applies to all transactions managed by the transaction manager, via the property <code>quarkus.transaction-manager.default-transaction-timeout</code>, specified as a duration.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The format for durations uses the standard <code>java.time.Duration</code> format.
You can learn more about it in the <a href="https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-">Duration#parse() javadoc</a>.</p>
</div>
<div class="paragraph">
<p>You can also provide duration values starting with a number.
In this case, if the value consists only of a number, the converter treats the value as seconds.
Otherwise, <code>PT</code> is implicitly prepended to the value to obtain a standard <code>java.time.Duration</code> format.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The default value is 60 seconds.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuring-transaction-node-name-identifier"><a class="anchor" href="#configuring-transaction-node-name-identifier"></a>Configuring transaction node name identifier</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Narayana, as the underlying transaction manager, has a concept of a unique node identifier.
This is important if you consider using XA transactions that involve multiple resources.</p>
</div>
<div class="paragraph">
<p>The node name identifier plays a crucial part in the identification of a transaction.
The node name identifier is forged into the transaction id when the transaction is created.
Based on the node name identifier, the transaction manager is capable of recognizing the XA transaction
counterparts created in database or JMS broker. The identifier makes possible for the transaction manager
to roll back the transaction counterparts during recovery.</p>
</div>
<div class="paragraph">
<p>The node name identifier needs to be unique per transaction manager deployment.
And the node identifier needs to be stable over the transaction manager restarts.</p>
</div>
<div class="paragraph">
<p>The node name identifier may be configured via the property <code>quarkus.transaction-manager.node-name</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="why-always-having-a-transaction-manager"><a class="anchor" href="#why-always-having-a-transaction-manager"></a>Why always having a transaction manager?</h2>
<div class="sectionbody">
<div class="dlist">
<dl>
<dt class="hdlist1">Does it work everywhere I want to?</dt>
<dd>
<p>Yep, it works in your Quarkus application, in your IDE, in your tests, because all of these are Quarkus applications.
JTA has some bad press for some people.
I don&#8217;t know why.
Let&#8217;s just say that this is not your grand&#8217;pa&#8217;s JTA implementation.
What we have is perfectly embeddable and lean.</p>
</dd>
<dt class="hdlist1">Does it do 2 Phase Commit and slow down my app?</dt>
<dd>
<p>No, this is an old folk tale.
Let&#8217;s assume it essentially comes for free and let you scale to more complex cases involving several datasources as needed.</p>
</dd>
<dt class="hdlist1">I don&#8217;t need transaction when I do read only operations, it&#8217;s faster.</dt>
<dd>
<p>Wrong.<br>
First off, just disable the transaction by marking your transaction boundary with <code>@Transactional(NOT_SUPPORTED)</code> (or <code>NEVER</code> or <code>SUPPORTS</code> depending on the semantic you want).<br>
Second, it&#8217;s again fairy tale that not using transaction is faster.
The answer is, it depends on your DB and how many SQL SELECTs you are making.
No transaction means the DB does have a single operation transaction context anyways.<br>
Third, when you do several SELECTs, it&#8217;s better to wrap them in a single transaction because they will all be consistent with one another.
Say your DB represents your car dashboard, you can see the number of kilometers remaining and the fuel gauge level.
By reading it in one transaction, they will be consistent.
If you read one and the other from two different transactions, then they can be inconsistent.
It can be more dramatic if you read data related to rights and access management for example.</p>
</dd>
<dt class="hdlist1">Why do you prefer JTA vs Hibernate&#8217;s transaction management API</dt>
<dd>
<p>Managing the transactions manually via <code>entityManager.getTransaction().begin()</code> and friends lead to a butt ugly code with tons of try catch finally that people get wrong.
Transactions are also about JMS and other database access, so one API makes more sense.</p>
</dd>
<dt class="hdlist1">It&#8217;s a mess because I don&#8217;t know if my JPA persistence unit is using <code>JTA</code> or <code>Resource-level</code> Transaction</dt>
<dd>
<p>It&#8217;s not a mess in Quarkus :)
Resource-level was introduced to support JPA in a non managed environment.
But Quarkus is both lean and a managed environment so we can safely always assume we are in JTA mode.
The end result is that the difficulties of running Hibernate ORM + CDI + a transaction manager in Java SE mode are solved by Quarkus.</p>
</dd>
</dl>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
